除了 Python,为什么机器学习还需要一种新的编程语言?
点击上方“CSDN”,选择“置顶公众号”
关键时刻,第一时间送达!
编者按:任何足够复杂的机器学习系统都需要一个特定的、非强制要求、优弊共存的编程语言。如今 Python 虽然在人工智能领域应用广泛,但是也存在一定的弊端,那么是否有必要为机器学习量身打造一门新的编程语言?而究竟什么样的编程语言才是最适合机器学习呢?接下来,本文将为大家一一揭晓答案。
作为一名编程人员,随着机器学习(ML)的爆发式发展,我们看到开发者为 ML 构建了很多复杂的模型和框架。在这些支持循环和递归的编程结构的先进模型推动之下,ML 领域涌现出大量的程序。同时,在我们构建这些程序的工具中也出现了一些有趣的问题,这里的工具也指的就是 -- 编程语言。
虽然机器学习领域没有一个专门的编程语言,但是有很多框架或库都提供基于 Python 的 API(比如 TensorFlow),又或者将 Python 用作建模语言(比如 PyTorch)。如今 Python 虽然在人工智能领域应用广泛,但是也存在一定的弊端,那么是否有必要为 ML 量身打造一门新的编程语言?如果需要的话,那么是源于何种原因?更重要的是,究竟什么样的编程语言才是最适合 ML?
常规的编程语言
一定程度上,TensorFlow(TF)及其 illk 文件(我们用 TensorFlow 举例,实际上可以用任何一种 define-before-run 的框架替代它,比如 CNTK 或者 MXNet)也可算作一种编程语言,尽管它们有很大的局限性。使用 Python 来进行 TF 编程,这可能会令人惊讶,但是考虑到在 TF 内部,它需要开发者编写 Python 代码来构建表达式树(https://www.tensorflow.org/programmers_guide/graphs),然后进行评估,也就可以理解了。
实际上,你可以使用任何语言编写出“lazy”风格的 TensorFlow。比如下面的 JavaScript 代码,它使用这种风格实现一个简单的 add 函数:
function add(a,b) {
return `${a}+${b}`;
}
x = 1; y = 2
z = add('x', 'y') // 'x+y'
eval(z) // 3
x = 4
eval(z) // 6
此处我们使用了元编程——用代码操作另一些代码。在以上的案例中,元语言和目标语言都是 JavaScript,它们是相同的,但它们也可以是其他语言(比如 C 语言),我们可以使用一种数据结构(AST:https://en.wikipedia.org/wiki/Abstract_syntax_tree)替代字符串,这原则是一样的。在 TensorFlow 中,Python 扮演者元语言的角色,可以使用它来调用编写 TF 图形库的语言(TensorFlow 图形库的数据流基于AST)。尽管 TensorFlow 的图形库支持像变量范围(https://www.tensorflow.org/programmers_guide/variables)和控制流(https://www.tensorflow.org/api_docs/python/tf/cond)这样的构造,但不是使用 Python 语法,而是通过 API 来操作这些构造。
TensorFlow 和其类似的工具都以库的形式呈现,但它们并不寻常。大多数库提供了一套简单的函数和数据结构,而不是一个全新的编程系统和运行时。使用这种复杂的方法的原因是什么呢?
为什么机器学习需要一种新的语言?
构建一种新语言的主要原因其实很简单:ML 研究具有极高的计算需求,需要简化建模语言使得添加特定领域的优化和特征变得更加容易。训练模型需要优秀的硬件支持,以及良好的数值、较低的解释器开销和多种并行性的支持。像 Python 这样的通用语言正好提供了这些功能,TensorFlow 可以无缝地处理它们。
尽管也存在一些障碍。这些优化依然令人印象深刻,它依赖于简化假设(ML 模型不会递归,或者需要自定义渐变,对吗?),这使得应用优化或部署到小型设备更容易。不幸的是,对于工程师来说,模型的复杂性已经增加了,研究人员又喜欢违反这些假设。模型现在需要条件分支,重复循环,甚至基于树的递归(https://arxiv.org/pdf/1503.00075.pdf)。在许多 ML 领域,包括神经网络(https://blog.keras.io/the-future-of-deep-learning.html)和概率编程(https://eng.uber.com/pyro/),模型越来越像程序,其中包括对其他程序的解释(例如程序生成器(https://arxiv.org/pdf/1705.03633.pdf和解释器(https://arxiv.org/abs/1605.06640))以及蒙特卡罗树搜索这样的不可微分组件。越来越多的模型和开创性的结果都需要灵活性和高性能运行时的支持,想要满足这两项指标是非常具有挑战的。
使用复杂的树形结构数据(如斯坦福大学的 Sentiment Treebank 进行机器学习,需要可微分的递归算法)
这种方法有一个缺点,至少在目前的版本中存在,那就是需要前文讨论的元编程的支持。构建和评估表达式树给程序员和编译器都会带来额外的负担。由于当前的代码有两个运行时,每个运行时都有不同的语言语义,所以解释起来会变得困难,比如单步调试就不会像一种语言那样方便。为新运行时创建一个语法语言就可以解决这个问题,但是这就意味着需要创建一个全新的编程语言。当我们已经有了流行的用于处理数据的编程语言时,是否还有必要创建一个新的语言呢?
可以只使用 Python 吗?
随着 ML 模型需要编程语言的功能越来越多,Chainer 神经网络框架开创了一种“define-b-run(https://arxiv.org/pdf/1701.03980.pdf)”的方法,其中的 Python 程序本身就是一个模型,使用运行时自动微分(AD)来导出。从可用性的角度来看,这是非常棒的:如果你想要一个基于树运行的递归模型,只需用Python进行编码,然后让 AD 来导出!感觉上的差异会很大,用新奇的想法来实现的方法对研究来说是无价的。
然而,扩展 Python 以满足 ML 的繁重计算需求远比你想象的要困难得多。想要复制优化 Python 从而提升速度的工作量非常巨大,编程社区对此充满期待,但事实上并没有使 Python 变得更快。Python 的语义也决定了它想要为小型设备提供模型级并行性或编译模型是非常困难的。
机器学习的专属语言是什么样的?
机器学习对语言级设计问题的要求很少。但这并没有什么特殊,在正式解释和验证或集群计算等领域,新的量身定制的语言已被证明是一个有效的解决方案。同样,我们希望看到有新的或现有的语言能够满足 ML 所需的数值、可微分、可并行甚至是概率计算。
ML 语言面临的一个明显的挑战是在性能方面需要取得一致性,而早期的混合方法想要满足这一点则需要更多的开发。我们预计未来的 ML 运行时将需要支持任意混合的方法,并且需要在编译动态代码时更好地部署。理想情况下,将只有单一、灵活的“图形格式”(或 AST)。AST 应该有一个语法和静态描述的动态行为(例如,用一个 for 循环)——换句话说,它应该看起来更像一个标准的编程语言。
可编程语义将开辟新的灵活性,并且可以通过类似于宏的特征来提供。这将指定代码具有纯数据流语义的位置(与标准命令语义相反,标准命令语义更灵活,但可能包括不安全的副作用优化),从而允许在核心系统之上构建像多 GPU 这样的功能。它也可以允许概率编程语言所需的各种程序操作,或者 NLP 模型中通常通过手工实现的向量化(批处理)过程。
与 PL 社区一样,ML 工程师也应该密切关注传统的自动微分(AD)社区。ML 语言可以从支持一流派生而设计的语言中获得灵感。这样的语言可以很容易地将符号与运行时技术混合在一起,混合正向和反向模式AD(用于改进性能和内存使用),并且区分 GPU 内核——所有这些都不会损失性能。
ML 研究将越来越需要更强大的类型系统,用户定义的类型和更多的扩展手段。NVIDIA GPU 上硬编码对阵列式阵列的支持已经足够了。像稀疏机器学习、TPU、Nervana 等新硬件以及 ARM芯片或 iPhone 的 CoreML芯片等多种部署目标都需要更高水平的灵活性。对每个新开发的核心 C ++ 代码的大规模重构将不会扩展。
有了新增的硬件支持(或新的数据表示),用户可以通过高级代码很容易地完成,而不需要改变原来的系统。在这里,我们期望 ML 系统从现有的数字计算语言中获得灵感,这些语言已经可以轻松地处理这些任务。
类型系统还具备安全性的优势,但是目前的类型系统并不适合阵列尺寸的大量代码(例如,空间 vs 通道 vs 图像批处理尺寸)。这些区别留给纯粹的约定,排列代码没有错误的保护,留下更多的阵列感知型系统的空间。我们预计动态类型的趋势将继续,主要是由于从业者偏好交互性和脚本,但希望看到更多的创新,如 CNTK 的动态维度(https://cntk.ai/pythondocs/sequence.html)。
ML 工程师对传统的软件工程问题越来越感兴趣,如维护和扩展生产系统。该 ML编程模型使得它更难创建组件之间的抽象障碍和接口,模型的重新训练可以轻松打破向后兼容性。ML 语言可能会像常规语言一样将这些问题的解决方案结合起来,但这仍然是一个开放的设计问题。
软件工程 2.0?
任何新语言的缺点是它需要一个新的库生态系统,只有为新的运行时编写的代码才能从中受益。例如,TensorFlow 的开发人员并未使用 Python 现有的生态系统,而是为图像处理和文件 IO 重新编写了库,正是这些付出像 SciPy 这样的项目才得以产生。这可能是唯一的出路,但 ML 从业者不应该从数字和 HPC 社区中分裂出去。一个理想的 ML 生态系统是一个理想的数字生态系统,反之亦然,这些社区之间的合作将使每个人的努力倍增。
结论
机器学习模型已经成为构建更高层次、更复杂抽象的通用信息处理系统的方法,且机器学习拥有递归、高阶模型、甚至堆栈机器和语言解释器都是作为基本组件的组合来实现的。ML 是一种新的编程范式,虽然在运算、微分和并行方面有些怪异,但在任何工程领域,ML 现有的工具都将对工作范围和质量产生深远的影响。
所有这些都表明 ML 系统的设计人员面临着巨大的挑战。但是,虽然这是事实,但还是有一些好消息:在过去的几十年中,语言研究人员已经深入探索了同样的问题。为了真正把这个新领域的潜力发挥到最大,机器学习和编程语言社区必须联合起来,真正的挑战是整合这两个群体的不同专业知识。
我们能否建立一套具有一流运算、派生和并行能力的系统,并且能够利用传统编程语言的优势?这是未来十年编程语言必须回答的基本问题。
原文:On Machine Learning and Programming Languages
链接:https://julialang.org/blog/2017/12/ml&pl
作者:Mike Innes (Julia Computing)、David Barber (UCL)、Tim Besard (UGent)、James Bradbury (Salesforce Research)、Valentin Churavy (MIT)、Simon Danisch (MIT)、Alan Edelman (MIT)、Stefan Karpinski (Julia Computing)、Jon Malmaud (MIT)、Jarrett Revels (MIT)、Viral Shah (Julia Computing)、Pontus Stenetorp (UCL) 和 Deniz Yuret (Koç University)。
译者:安翔
责编:苏宓
————— END —————
重大改革:Python 语言将被加入高考科目,VB 惨被淘汰!